package com.xinke.component.common.util.collection;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.ArrayUtil;

import java.util.Arrays;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Description:Array 工具类
 *
 * @Author yzx
 * @Create 2025/3/11 23:00
 * @Version 1.0
 */
public class ArrayUtils {
    /**
     * 将 object 和 newElements 合并成一个数组
     *
     * @param object 对象
     * @param newElements 数组
     * @param <T> 泛型
     * @return 结果数组
     *
     * 解释：这是一个用于将单个Consumer<T>对象与一个可变参数的Consumer<T>数组合并的实用方法，返回一个新的Consumer<T>数组，
     *      其中原对象位于数组开头，可变参数元素紧随其后。
     * 泛型 <T>
     * 方法操作的类型由调用者决定，确保所有Consumer的参数类型一致。
     * 参数
     * object: 单个Consumer<T>对象，将被添加到数组开头。
     * newElements: 可变参数的Consumer<T>数组，原有元素会被追加到新数组中。
     * 返回值
     * 合并后的Consumer<T>[]数组，object在前，newElements在后。
     * @SafeVarargs注解
     * 标记该方法对可变参数的操作是类型安全的（避免泛型数组的堆污染警告）。
     */
    @SafeVarargs
    public static <T> Consumer<T>[] prepend(Consumer<T> object, Consumer<T>... newElements) {
        newElements = (newElements == null) ? new Consumer[0] : newElements;
        if (object == null) {
            return newElements;
        }
        Consumer<T>[] result = ArrayUtil.newArray(Consumer.class, 1 + newElements.length);
        result[0] = object;
        System.arraycopy(newElements, 0, result, 1, newElements.length);

        // 返回不可变数组 避免调用者意外修改内部数组：
        return Arrays.copyOf(result, result.length); // 返回副本
        //return result;
    }

    public static <T, V> V[] toArray(Collection<T> from, Function<T, V> mapper) {
        return toArray(CollectionUtils.convertList(from, mapper));
    }

    @SuppressWarnings("unchecked")
    public static <T> T[] toArray(Collection<T> from) {
        if (CollectionUtil.isEmpty(from)) {
            return (T[]) (new Object[0]);
        }
        return ArrayUtil.toArray(from, (Class<T>) IterUtil.getElementType(from.iterator()));
    }

    public static <T> T get(T[] array, int index) {
        if (null == array || index >= array.length) {
            return null;
        }
        return array[index];
    }
}
